<!DOCTYPE html>
<html>

<body>

    <style>
        body {
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100vh;
            margin: 0;
        }

        input {
            position: absolute;
            top: 20px;
        }

        #percentValue {
            position: absolute;
            top: 20px;
            left: 220px;
        }
        #progress-arc__svg {
            --color: #2196F3;
        }
        #progress-arc__svg #progress-arc {
            stroke: var(--color)
        }
        #progress-arc__svg text {
            fill: var(--color)
        }
    </style>
    <!-- 输入框 -->
    <input type="range" min="0" max="100" value="75" id="percentInput">
    <span id="percentValue">75%</span>

    <!-- SVG画布 -->
    <svg id="progress-arc__svg" width="20vw" height="20vw" viewBox="59 39 107 90">
        <!-- 背景弧线 -->
        <path id="bg-arc" d="M75,125 A50,50 0 1 1 150,125" fill="none" stroke="#eee" stroke-width="6" stroke-linecap="round" />

        <!-- 前景进度弧 -->
        <path id="progress-arc" d="M75,125 A50,50 0 1 1 150,125" fill="none" stroke-width="6"
            stroke-linecap="round" />

        <!-- 动态生成刻度线 -->
        <g id="ticks" transform="translate(112, 92)" stroke="#666"></g>

        <!-- 中心文本 -->
        <text x="112" y="92" text-anchor="middle" dy="0.3em" font-size="20" font-weight="bold">
            <tspan font-size="20" x="110" align="right">100</tspan>
            <tspan font-size="11" y="95" x="133">%</tspan>
        </text>
    </svg>

    <script>
        const progressArc = document.getElementById('progress-arc');
        const percentInput = document.getElementById('percentInput');
        const percentValue = document.getElementById('percentValue');
        const ticks = document.getElementById('ticks');

        function updateGauge(percent) {
            // 计算弧长和进度
            const radius = 50;
            const circumference = 2 * Math.PI * radius * (270 / 360);
            const offset = circumference - (percent / 100 * circumference);

            // 更新进度条
            progressArc.style.strokeDasharray = `${circumference} ${circumference}`;
            progressArc.style.strokeDashoffset = offset;

            // 更新文本
            percentValue.textContent = `${percent}%`;
            document.querySelector('tspan:nth-child(1)').textContent = `${percent}`;
        }

        // 更新刻度线
        updateTicks();
        function updateTicks() {
            // 清除现有的刻度线
            ticks.innerHTML = '';

            // 计算刻度数
            const tickCount = 30; // 假设我们要生成10个刻度
            const tickAngle = (270 / tickCount); // 每个刻度的角度

            // 生成刻度线
            for (let i = 0; i <= tickCount; i++) {
                const angle = -135 + i * tickAngle; // 从-135度开始
                const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
                line.setAttribute('y1', '-35');
                line.setAttribute('y2', (i % 3)? '-38': '-39');
                line.setAttribute('transform', `rotate(${angle})`);
                ticks.appendChild(line);
            }
        }

        // 初始化
        const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
        path.setAttribute('d', 'M50,125 A50,50 0 1 1 150,125');
        const circumference = path.getTotalLength();
        progressArc.style.strokeDasharray = `${circumference} ${circumference}`;    // Update the dash array to match the new circumference calculation in updateGauge() function below: `const circumference = 2 * Math.PI * radius;` instead of `const circumference = path.getTotalLength();` which was used before but now we are using the calculated value directly from the formula above so no need to use `path.getTotalLength()` anymore as it was just a placeholder for the actual calculation done here now with `const circumference = path.getTotalLength();` being replaced by `const circumference = 2 * Math.PI * radius;` which is what we want to use going forward so no need for that extra step anymore and can just remove it completely from here onwards...
        progressArc.style.strokeDasharray = `${circumference} ${circumference}`;
        progressArc.style.strokeDashoffset = circumference * 0.25; // 初始75%
        
        updateGauge(75); // 初始值

        // 绑定输入事件
        percentInput.addEventListener('input', (e) => {
            updateGauge(e.target.value);
        });
    </script>
</body>

</html>